// 通过化简可知，这道题要求的是将分成的每部分的平方和都划到最小即可
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int N = 20, M = 10;
const double INF = 1e9;
// f[x1][y1][x2][y2][n]表示将x1,y1到x2, y2分成k块矩阵的每部分的和最小
double f[M][M][M][M][N];
int n;
double x_mid;
// 由于要用到总和，用二维前缀和进行优化
int g[M][M], s[M][M];

int get_sum(int x1, int y1, int x2, int y2)
{
    return s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1];
}

double get(int x1, int y1, int x2, int y2)
{
    double sum = get_sum(x1, y1, x2, y2);
    return sum * sum / n;
}

double dfs(int x1, int y1, int x2, int y2, int k)
{
    double &v = f[x1][y1][x2][y2][k];
    if (v >= 0)
        return v;
    if (k == 1)
        return v = get(x1, y1, x2, y2);
    // 每次划分都可以有两种选择，横切和竖切
    // 并且每次选择之后还可以选择继续分割上面或者下面

    // 先枚举横切
    v = INF;
    for (int i = x1; i < x2; ++i)
    {
        v = min(v, get(x1, y1, i, y2) + dfs(i + 1, y1, x2, y2, k - 1));
        v = min(v, get(i + 1, y1, x2, y2) + dfs(x1, y1, i, y2, k - 1));
    }
    // 再枚举竖切
    for (int i = y1; i < y2; ++i)
    {
        // 左边不切
        v = min(v, get(x1, y1, x2, i) + dfs(x1, i + 1, x2, y2, k - 1));
        // 右边不切
        v = min(v, get(x1, i + 1, x2, y2) + dfs(x1, y1, x2, i, k - 1));
    }
    return v;
}

int main()
{
    cin >> n;
    for (int i = 1; i <= 8; ++i)
        for (int j = 1; j <= 8; ++j)
        {
            cin >> g[i][j];
            s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + g[i][j];
        }
    // 对于浮点数来说，memset成-1表示nan(not a number)
    memset(f, -1, sizeof f);
    x_mid = (double)s[8][8] / n;
    printf("%.3lf", sqrt(dfs(1, 1, 8, 8, n) - x_mid * x_mid));

    return 0;
}
